package org.posupe.candidatos;

public class RepositorioCandidatosLista implements RepositorioCandidatos {
	private Candidato candidato;

	private RepositorioCandidatosLista proximo;

	private int tamanho;

	public RepositorioCandidatosLista() {
		this.candidato = null;
		this.proximo = null;
		this.tamanho = 0;
	}

	public void inserir(Candidato candidato) {
		if (this.candidato == null) {
			this.candidato = candidato;
			this.proximo = new RepositorioCandidatosLista();
		} else {
			this.proximo.inserir(candidato);
		}

		this.tamanho++;
	}

	public void atualizar(Candidato candidato)
			throws CandidatoInexistenteException {
		if (this.candidato != null) {
			if (this.candidato.getCodigo().equals(candidato.getCodigo())) {
				this.candidato = candidato;
			} else {
				this.proximo.atualizar(candidato);
			}
		} else {
			throw new CandidatoInexistenteException(candidato.getCodigo());
		}
	}

	public void remover(String cpf) throws CandidatoInexistenteException {
		if (this.candidato != null) {
			if (this.candidato.getCodigo().equals(cpf)) {
				this.candidato = this.proximo.candidato;
				this.proximo = this.proximo.proximo;
			} else {
				this.proximo.remover(cpf);
			}

			this.tamanho--;
		} else {
			throw new CandidatoInexistenteException(cpf);
		}
	}

	public Candidato procurar(String cpf) throws CandidatoInexistenteException {
		Candidato retorno = null;

		if (this.candidato != null) {
			if (this.candidato.getCodigo().equals(cpf)) {
				retorno = this.candidato;
			} else {
				retorno = this.proximo.procurar(cpf);
			}
		} else {
			throw new CandidatoInexistenteException(cpf);
		}

		return retorno;
	}

	public boolean existe(String cpf) {
		boolean retorno = false;
		if (this.candidato != null) {
			if (this.candidato.getCodigo().equals(cpf)) {
				retorno = true;
			} else {
				retorno = this.proximo.existe(cpf);
			}
		}
		return retorno;
	}

	public IteratorCandidatos procurar(Candidato candidato) {
		IteratorCandidatosArrayList resultado = new IteratorCandidatosArrayList();
		IteratorCandidatos candidatos = this.getIterator();

		while (candidatos.hasNext()) {
			Candidato nextCandidato = candidatos.next();
			if (nextCandidato.match(candidato)) {
				resultado.add(nextCandidato);
			}
		}

		return resultado;
	}

	public IteratorCandidatos getIterator() {
		IteratorCandidatosArrayList resultado = new IteratorCandidatosArrayList();
		RepositorioCandidatosLista proximoCandidato = this;
		int contador = 0;

		while (contador < this.tamanho) {
			resultado.add(proximoCandidato.candidato);
			proximoCandidato = proximoCandidato.proximo;
			contador++;
		}

		return resultado;
	}

}
